home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / AmigaSystem / Scalos / GuiGFXLib / src / guigfx_drawhandle.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-28  |  13.6 KB  |  568 lines

  1. /*********************************************************************
  2. ----------------------------------------------------------------------
  3.  
  4.     guigfx_drawhandle
  5.  
  6. ----------------------------------------------------------------------
  7. *********************************************************************/
  8.  
  9. #include <math.h>
  10. #ifdef MATH_68882
  11.     #include <m68881.h>
  12. #endif
  13.  
  14. #include <render/render.h>
  15. #include <libraries/cybergraphics.h>
  16. #include <utility/tagitem.h>
  17. #include <graphics/gfx.h>
  18. #include <graphics/view.h>
  19.  
  20. #include <proto/render.h>
  21. #include <proto/graphics.h>
  22. #include <proto/exec.h>
  23. #include <proto/utility.h>
  24. #include <proto/cybergraphics.h>
  25. //#include <proto/mathtrans.h>
  26.  
  27. #include <guigfx/guigfx.h>
  28.  
  29. #include "guigfx_global.h"
  30.  
  31.  
  32. #include "guigfx_yuvtab.c"
  33.  
  34. /*--------------------------------------------------------------------
  35.  
  36.     ReleasePenTab(pentab,colormap,numcolors)
  37.  
  38.     Gibt eine Pentab frei.
  39.  
  40. --------------------------------------------------------------------*/
  41.  
  42. void ReleasePenTab(UBYTE *pentab, struct ColorMap *cm, UWORD numcolors)
  43. {
  44.     int i;
  45.     
  46.     for(i=0; i<numcolors; ++i)
  47.     {
  48.         ReleasePen(cm,(ULONG)pentab[i]);
  49.     }
  50. }
  51.  
  52.  
  53. /*--------------------------------------------------------------------
  54.  
  55.     success = ObtainPenTab(palette,colormap,pentab,numcolors,precision)
  56.  
  57.     Fordert eine Palette an und hinterlegt die Pens in einer Pentab.
  58.  
  59. --------------------------------------------------------------------*/
  60.  
  61. BOOL ObtainPenTab (    PALETTE palette, struct ColorMap *cm, UBYTE *pentab,
  62.                     UWORD numcolors, ULONG precision )
  63. {
  64.     int i;
  65.     LONG pen;
  66.     ULONG rgb[3];
  67.     UWORD count = 0;
  68.  
  69.     for(i=0; i < numcolors; ++i)
  70.     {
  71.         ExportPalette(palette,rgb,    RND_PaletteFormat,PALFMT_RGB32,
  72.                                     RND_FirstColor,i,
  73.                                     RND_NumColors,1,
  74.                                     TAG_DONE);
  75.  
  76.         pen = ObtainBestPen(cm,rgb[0],rgb[1],rgb[2],OBP_Precision,precision,TAG_DONE);
  77.  
  78.         if (pen == -1)
  79.         {
  80.             ReleasePenTab(pentab,cm,count);
  81.             return FALSE;
  82.         }
  83.         else
  84.         {
  85.             pentab[i] = (UBYTE) pen;
  86.             count++;
  87.         }
  88.     }
  89.  
  90.     return TRUE;
  91. }
  92.  
  93.  
  94. /*********************************************************************
  95. ----------------------------------------------------------------------
  96.  
  97.     ReleaseDrawHandle(drawhandle)
  98.  
  99.     gibt die allozierten Farben eines DrawHandles frei
  100.     und löscht das DrawHandle.
  101.  
  102. ----------------------------------------------------------------------
  103. *********************************************************************/
  104.  
  105. void SAVE_DS ASM ReleaseDrawHandle(REG(a0) DRAWHANDLE *dh)
  106. {
  107.     if (dh)
  108.     {
  109.         if(dh->mapengine)
  110.         {
  111.             DeleteMapEngine(dh->mapengine);
  112.         }
  113.     
  114.         if(dh->realpalette)
  115.         {
  116.             DeletePalette(dh->realpalette);
  117.         }
  118.     
  119.         if(dh->mainnumcolors)
  120.         {
  121.             ReleasePenTab(dh->mainpentab, dh->colormap, dh->mainnumcolors);
  122.         }    
  123.     
  124.         if(dh->mainpalette)
  125.         {
  126.             DeletePalette(dh->mainpalette);
  127.         }
  128.     
  129.         if(dh->rasthandle)
  130.         {
  131.             DeleteRastHandle(dh->rasthandle);
  132.         }
  133.     
  134.         FreeRenderVec(dh);
  135.     }
  136. }
  137.  
  138.  
  139. /*********************************************************************
  140. ----------------------------------------------------------------------
  141.  
  142.     drawhandle = ObtainDrawHandleA(rastport, colormap, psm, tags);
  143.  
  144.     Fordert die Farben einer PenShareMap von einer colormap an
  145.     und erzeugt dafür ein drawhandle für einen rastport.
  146.  
  147.     OBP_Precision
  148.     GGFX_DitherMode                bestimmt Dither-Modus
  149.     GGFX_DitherAmount
  150.     GGFX_DitherThreshold        Schwellwert für Autodither
  151.     GGFX_AutoDither                default: TRUE
  152.     GGFX_MaxAllocPens            default: keine Beschränkung
  153.     GGFX_ModeID
  154.     GGFX_BGColor                definierte hintergrundfarbe
  155.  
  156. ----------------------------------------------------------------------
  157. *********************************************************************/
  158.  
  159. DRAWHANDLE SAVE_DS ASM *ObtainDrawHandleA(
  160.     REG(a0) PSM *psm,
  161.     REG(a1) struct RastPort *rp,
  162.     REG(a2) struct ColorMap *cm,
  163.     REG(a3) TAGLIST tags)
  164. {
  165.     DRAWHANDLE *dh;
  166.  
  167.  
  168.     if(dh = AllocRenderVecClear(MemHandler, sizeof(DRAWHANDLE)))
  169.     {
  170.         BOOL success = FALSE;
  171.  
  172.         dh->dithermode =
  173.                 GetTagData(GGFX_DitherMode, DEFAULT_DITHERMODE, tags);
  174.  
  175.         dh->bgcolor =
  176.                 GetTagData(GGFX_BGColor, 0xffffffff, tags);
  177.  
  178.         dh->autodither =
  179.                 GetTagData(GGFX_AutoDither, DEFAULT_AUTODITHER, tags);
  180.  
  181.         dh->ditherthreshold =
  182.                 GetTagData(GGFX_DitherThreshold, env_autoditherthreshold, tags);
  183.  
  184.         dh->ditheramount =
  185.                 GetTagData(GGFX_DitherAmount, DEFAULT_DITHERAMOUNT, tags);
  186.  
  187.         dh->modeID =
  188.                 GetTagData(GGFX_ModeID, INVALID_ID, tags);
  189.  
  190.  
  191.         DB(kprintf("Creating drawhandle with threshold %ld\n", dh->ditherthreshold));
  192.  
  193.         if (dh->rasthandle = CreateRastHandle(rp, dh->modeID))
  194.         {
  195.             success = TRUE;
  196.  
  197.             if (!dh->rasthandle->truecolor)
  198.             {
  199.                 //    wenn keine Pensharemap übergeben wurde, einen
  200.                 //    9bit-Farbraum erzeugen
  201.             
  202.                 if (!(dh->psm = psm))
  203.                 {
  204.                     success = FALSE;
  205.  
  206.                     if (psm = CreatePenShareMapA(NULL))
  207.                     {
  208.                             struct TagItem tags[2] = {{GGFX_PixelFormat, PIXFMT_0RGB_32}, {TAG_DONE}};
  209.                             success = !!AddPixelArrayA(psm, yuvtab, 6*6*6, 1, tags);
  210.                     
  211.                     #if 0
  212.                         ULONG *colortable;
  213.                         if (colortable = AllocRenderVec(MemHandler, sizeof(ULONG) * 6*6*6))
  214.                         {
  215.                             int y,u,v;
  216.                             DOUBLE Y, U, V;
  217.                             ULONG *p = colortable;
  218.                             struct TagItem tags[2] = {{GGFX_PixelFormat, PIXFMT_0RGB_32}, {TAG_DONE}};
  219.                             
  220.                             for (y = 0; y < 6; ++y)
  221.                             {
  222.                                 for (u = 0; u < 6; ++u)
  223.                                 {
  224.                                     for (v = 0; v < 6; ++v)
  225.                                     {
  226.                                             Y = (255 * y / 5);
  227.                                             U = (222 * u / 5) - 111;
  228.                                             V = (312 * v / 5) - 156;
  229.                                             
  230.                                             *p++ =
  231.                                                     ((int)(Y + 1.140 * V) << 16) +
  232.                                                     ((int)(Y - 0.396 * U - 0.581 * V) << 8) +
  233.                                                     (int)(Y + 2.029 * U);
  234.                                     }
  235.                                 }
  236.                             }
  237.                             success = !!AddPixelArrayA(psm, colortable, 6*6*6, 1, tags);
  238.                             FreeRenderVec(colortable);
  239.                         }
  240.                     #endif
  241.                     
  242.                     }
  243.                 }
  244.  
  245.  
  246.                 if (success)
  247.                 {
  248.                     ObtainSemaphore(&psm->semaphore);
  249.  
  250.                     if (psm->modified)
  251.                     {
  252.                         if (psm->histogram)
  253.                         {
  254.                             DeleteHistogram(psm->histogram);
  255.                             psm->histogram = NULL;
  256.                         }
  257.                     }
  258.             
  259.                     if (!psm->histogram)
  260.                     {
  261.                         success = FALSE;
  262.             
  263.                         if(psm->histogram = CreateHistogram(RND_RMHandler, MemHandler, 
  264.                             RND_HSType, psm->hstype, TAG_DONE))
  265.                         {
  266.                             if (!IsListEmpty(&psm->colorlist))
  267.                             {
  268.                                 struct Node *node = (struct Node *) psm->colorlist.lh_Head;
  269.                                 struct Node *nextnode;
  270.                                 
  271.                                 COLORHANDLE *ch;
  272.                                 DOUBLE minf = 10000, f;
  273.                                 success = TRUE;
  274.                 
  275.                                 /* Gewichtungsfaktor für Addhistogram berechnen */
  276.                             
  277.                                 while (nextnode = node->ln_Succ)
  278.                                 {
  279.                                     ch = (COLORHANDLE *)node;
  280.                                     f = (DOUBLE) ch->weight / (DOUBLE) ch->numpixels;
  281.                                     if (f < minf)
  282.                                     {
  283.                                         minf = f;
  284.                                     }
  285.                                     node = nextnode;
  286.                                 }
  287.                                 node = (struct Node *) psm->colorlist.lh_Head;
  288.                             
  289.                                 while ((nextnode = node->ln_Succ) && success)
  290.                                 {
  291.                                     ch = (COLORHANDLE *)node;
  292.                                     if (ch->histogram)
  293.         
  294.                                     success = (AddHistogram(psm->histogram, ch->histogram->histogram, 
  295.                                         RND_Weight, (ULONG) ((DOUBLE) ch->weight / ((DOUBLE) ch->numpixels * (DOUBLE) minf)),
  296.                                         TAG_DONE) == ADDH_SUCCESS);
  297.         
  298.                                     node = nextnode;
  299.                                 }
  300.                             }
  301.                         }
  302.             
  303.                         if (success)
  304.                         {
  305.                             psm->modified = FALSE;
  306.                         }
  307.                     }
  308.             
  309.             
  310.                     if (success)
  311.                     {
  312.                         ULONG maxcolors;
  313.                         ULONG maxallocpens;
  314.                         ULONG histoColors;
  315.                         UWORD firstcolor;
  316.     
  317.                         success = FALSE;
  318.     
  319.                         switch (dh->rasthandle->colormode)
  320.                         {
  321.                             case COLORMODE_HAM6:
  322.                                 maxcolors = 15;
  323.                                 firstcolor = 1;
  324.                                 break;
  325.  
  326.                             case COLORMODE_HAM8:
  327.                                 maxcolors = 63;
  328.                                 firstcolor = 1;
  329.                                 break;
  330.  
  331.                             default:
  332.                                 if ((dh->dithermode != DITHERMODE_NONE) /*&& (dh->autodither)*/)
  333.                                 {
  334.                                     maxcolors = 254;
  335.                                     firstcolor = 2;
  336.                                 }
  337.                                 else
  338.                                 {
  339.                                     maxcolors = 256;
  340.                                     firstcolor = 0;
  341.                                 }
  342.             /*
  343.                                 if (dh->bgcolor != 0xffffffff)
  344.                                 {
  345.                                     maxcolors--;
  346.                                     firstcolor++;
  347.                                 }
  348.             */
  349.                                 break;
  350.                         }
  351.                         
  352.                 
  353.                         dh->colormap = cm;
  354.         
  355.                         dh->precision = GetTagData(OBP_Precision, PRECISION_IMAGE, tags);
  356.         
  357.                         maxallocpens = GetTagData(GGFX_MaxAllocPens, maxcolors, tags);
  358.                         
  359.                         if((histoColors = QueryHistogram(psm->histogram, RND_NumColors)) > 0)
  360.                         {
  361.                             LONG mainColors;
  362.                             struct PaletteExtra *pe;
  363.  
  364.                             mainColors = MIN(histoColors, maxallocpens);
  365.                     
  366.                             if (!dh->rasthandle->truecolor)
  367.                             {
  368.                                 DB(kprintf("ObtainDrawHandle: bitmap is not truecolor.\n"));
  369.         
  370.                                 if (pe = cm->PalExtra)
  371.                                 {
  372.                                     UWORD numsharable;
  373.                                     ObtainSemaphoreShared(&pe->pe_Semaphore);
  374.                                     numsharable = pe->pe_NFree;
  375.                                     ReleaseSemaphore(&pe->pe_Semaphore);
  376.                                     if (numsharable > 1)
  377.                                     {
  378.                                         mainColors = MIN(numsharable*3, mainColors);
  379.                                     }
  380.                                 }
  381.                             }
  382.             
  383.                             if(dh->mainpalette = CreatePalette(RND_RMHandler, MemHandler,
  384.                                     RND_HSType, psm->hstype, TAG_DONE))
  385.                             {        
  386.                                 DB(kprintf("ObtainDrawHandle: extracting palette.\n"));
  387.             
  388.                                 if (ExtractPalette(psm->histogram, dh->mainpalette,
  389.                                     mainColors, RND_ColorMode, dh->rasthandle->colormode,
  390.                                     RND_FirstColor, firstcolor,    
  391.                                     RND_RGBWeight, DEFAULT_RGBWEIGHT, 
  392.                                     TAG_DONE) == EXTP_SUCCESS)
  393.                                 {
  394.                                     ULONG rgb[3];
  395.     
  396.                                     if (!dh->rasthandle->truecolor)
  397.                                     {
  398.                                         int insertpos = 0;
  399.                                         switch (dh->rasthandle->colormode)
  400.                                         {
  401.                                             case COLORMODE_CLUT:
  402.                                             {
  403.                                                 if (dh->dithermode != DITHERMODE_NONE)
  404.                                                 {
  405.                                                     //    schwarz und weiß einfügen für dithering
  406.                                                 
  407.                                                     ULONG rgb[2] = {0x00000000, 0x00ffffff};
  408.                                                     DB(kprintf("ObtainDrawHandle: inserting black & white for dithering.\n"));
  409.                                                     ImportPalette(dh->mainpalette, rgb, 2,
  410.                                                         RND_NewPalette, FALSE, TAG_DONE);
  411.                                                     mainColors += 2;
  412.                                                     insertpos += 2;
  413.                                                 }
  414.  
  415.                             /*
  416.                                                 if (dh->bgcolor != 0xffffffff)
  417.                                                 {
  418.                                                     //    definierte hintergrundfarbe einfügen
  419.                                                 
  420.                                                     DB(kprintf("ObtainDrawHandle: inserting background color.\n"));
  421.                                                     ImportPalette(dh->mainpalette, &dh->bgcolor, 1,
  422.                                                         RND_FirstColor, insertpos, RND_NewPalette, FALSE, TAG_DONE);
  423.                                                     mainColors ++;
  424.                                                 }
  425.                             */
  426.  
  427.                                                 SortPalette(dh->mainpalette, 
  428.                                                 //    PALMODE_SATURATION,
  429.                                                 //    PALMODE_POPULARITY,    
  430.                                                         PALMODE_SIGNIFICANCE,
  431.                                                         RND_Histogram, psm->histogram, TAG_DONE);
  432.  
  433.                                                 break;
  434.                                             }
  435.  
  436.                                             case COLORMODE_HAM8:
  437.                                                 GetRGB32(cm, 0, 1, rgb);
  438.                                                 ImportPalette(dh->mainpalette, rgb, 1,
  439.                                                         RND_PaletteFormat, PALFMT_RGB32,
  440.                                                         RND_NewPalette, FALSE, TAG_DONE);
  441.                                                 break;
  442.     
  443.                                             case COLORMODE_HAM6:
  444.                                             {
  445.                                                 UWORD rgb;
  446.                                                 rgb = (UWORD) GetRGB4(cm, 0);
  447.                                                 ImportPalette(dh->mainpalette, &rgb, 1,
  448.                                                         RND_PaletteFormat, PALFMT_RGB4,
  449.                                                         RND_NewPalette, FALSE, TAG_DONE);
  450.                                                 break;
  451.                                             }
  452.                                         }
  453.                                     }
  454.             
  455.                                     if(ObtainPenTab(dh->mainpalette, cm,
  456.                                         dh->mainpentab, mainColors, dh->precision))
  457.                                     {
  458.         
  459.                                         DB(kprintf("ObtainDrawHandle: Pass 2 - %ld pens allocated.\n", mainColors));
  460.         
  461.                                         if(dh->realpalette)
  462.                                         {
  463.                                             DeletePalette(dh->realpalette);
  464.                                         }
  465.                             
  466.                                         if(dh->realpalette = CreatePalette(RND_HSType, psm->hstype,
  467.                                                 RND_RMHandler, MemHandler, TAG_DONE))
  468.                                         {
  469.                                             int i;
  470.     
  471.                                             switch (dh->rasthandle->colormode)
  472.                                             {
  473.                                                 case COLORMODE_HAM6:
  474.                                                 {
  475.                                                     UWORD rgb;
  476.                                                     for(i=0; i<mainColors; ++i)
  477.                                                     {
  478.                                                         rgb = (UWORD) GetRGB4(cm, dh->mainpentab[i]);
  479.                                                         ImportPalette(dh->realpalette, &rgb, 1,
  480.                                                             RND_PaletteFormat, PALFMT_RGB4,
  481.                                                                 RND_NewPalette, FALSE,
  482.                                                                 RND_FirstColor, i,
  483.                                                                 TAG_DONE);
  484.                                                     }
  485.                                                     break;
  486.                                                 }                                                
  487.                                                 default:
  488.                                                     for(i=0; i<mainColors; ++i)
  489.                                                     {
  490.                                                         GetRGB32(cm, dh->mainpentab[i], 1, rgb);
  491.                                                         ImportPalette(dh->realpalette, rgb, 1,
  492.                                                             RND_PaletteFormat, PALFMT_RGB32,
  493.                                                                 RND_NewPalette, FALSE,
  494.                                                                 RND_FirstColor, i,
  495.                                                                 TAG_DONE);
  496.                                                     }
  497.                                                     break;
  498.                                             }
  499.                                             
  500.                                             dh->mainnumcolors = mainColors;
  501.  
  502.                                             InitSemaphore(&dh->mapsemaphore);
  503.  
  504.                                             if (!dh->psm && psm)
  505.                                             {
  506.                                                 if ((!dh->rasthandle->truecolor) && (psm->hstype == HSTYPE_12BIT_TURBO))
  507.                                                 {
  508.                                                     dh->mapengine = CreateMapEngine(dh->realpalette,
  509.                                                     //        RND_Histogram, psm->histogram,
  510.                                                             RND_RMHandler, MemHandler, TAG_DONE);
  511.                                                 }
  512.                                             }
  513.         
  514.                                             if (dh->bgcolor != 0xffffffff)
  515.                                             {
  516.                                                 dh->bgpen = dh->mainpentab[BestPen(dh->mainpalette, dh->bgcolor)];
  517.                                                 
  518.                                             //         ObtainBestPen(cm, RED_RGB32(dh->bgcolor),
  519.                                             //            GREEN_RGB32(dh->bgcolor), BLUE_RGB32(dh->bgcolor),
  520.                                             //            OBP_Precision, dh->precision, TAG_DONE);
  521.                                             }
  522.                     /*                    else
  523.                                             {
  524.                                                 dh->bgpen = ObtainBestPen(cm, 0,0,0,
  525.                                                         OBP_Precision, PRECISION_GUI, TAG_DONE);
  526.                                                 dh->bgcolor = 0x000000;
  527.                                             }
  528.                     */
  529.                                             success = TRUE;
  530.                                         }
  531.                                     }
  532.                                 }                
  533.                             }
  534.                         }
  535.                     }
  536.  
  537.                     ReleaseSemaphore(&psm->semaphore);
  538.                 }
  539.  
  540.                 if (!dh->psm && psm)
  541.                 {
  542.                     //    es wurde keine PenShareMap übergeben, interne Pensharemap löschen
  543.                 
  544.                     DeletePenShareMap(psm);
  545.                 }
  546.  
  547.             }
  548.             #ifndef NDEBUG
  549.             else
  550.             {
  551.                 DB(kprintf("Bitmap is truecolor. No pens allocated.\n"));
  552.             }
  553.             #endif
  554.         }
  555.         
  556.         if (success == FALSE)
  557.         {
  558.             ReleaseDrawHandle(dh);
  559.             dh = NULL;
  560.         }
  561.  
  562.  
  563.     }
  564.         
  565.     return dh;
  566. }
  567.  
  568.